/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.is.ga;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;

/**
 *
 * @author oleg
 */
public class Solver {

    double matrix[][];
    int count;
    int chromosomeLength;

    public Solver(double[][] matrix, int count) {
        this.matrix = matrix;
        this.count = count;
        this.chromosomeLength = matrix.length;
    }

    public int[] solve() {
        Chromosome[] startChromosomes = initialize(count, matrix);

        for (int i = 0; i < 1; i++) {
            startChromosomes = this.multiplication(startChromosomes, 1.5);
            System.out.println(""+startChromosomes.length);
            startChromosomes = this.selection(startChromosomes, 0.4);
        }
        System.out.println("");
        int[] solution=new int[chromosomeLength];
        solution=startChromosomes[0].chromosome;
        for(int i=0;i<startChromosomes.length;i++){
            if (startChromosomes[i].getChromosome()[0]==0)
                return startChromosomes[i].getChromosome();
        }
        return solution;
    }

    private Chromosome[] initialize(int countOfChromosomes, double matrix[][]) {
        Chromosome chromosome[] = new Chromosome[countOfChromosomes];
        for (int i = 0; i < countOfChromosomes; ++i) {
            ChromosomeGenerator array = new ChromosomeGenerator(chromosomeLength);
            int geneticItem[] = new int[chromosomeLength];
            for (int j = 0; j < chromosomeLength; j++) {
                geneticItem[j] = array.getRandom();
            }
            chromosome[i] = new Chromosome(geneticItem, matrix);
        }
        return chromosome;
    }

    /**
     * Удаляет % неуспешных
     * @param chromosomes
     * @param percent < 1
     * @return
     */
    private Chromosome[] selection(Chromosome chromosomes[], double percent) {
        Chromosome selectionResult[] = new Chromosome[(int) (chromosomes.length * (1 - percent))];
        LinkedList<Chromosome> list=new LinkedList<Chromosome>();
        for(int i=0;i<chromosomes.length;i++){
            if(chromosomes[i].chromosome[0]==0){
                list.add(chromosomes[i]);
            }
        }
        chromosomes=new Chromosome[list.size()];
        Iterator<Chromosome> iterator = list.iterator();
        int i=0;
        while(iterator.hasNext()){
            chromosomes[i]=iterator.next();
            i++;
        }
        Arrays.sort(chromosomes);
        
        System.arraycopy(chromosomes, 0, selectionResult, 0, (int) (chromosomes.length * (1 - percent)));
double cost = chromosomes[0].getCost();
        return selectionResult;
    }

    /**
     * Размножение
     * @param chromosomes
     * @param percent > 1
     * @return
     */
    private Chromosome[] multiplication(Chromosome chromosomes[], double percent) {

        Chromosome multiplicationResult[] = new Chromosome[(int) Math.round(chromosomes.length * percent)];
        System.arraycopy(chromosomes, 0, multiplicationResult, 0, chromosomes.length);
        int num=0;
        try {
            for (int i = 0; i < chromosomes.length * (percent - 1); i++) {
                num=i;
                boolean solved = false;
                //выбираем из всех хромосом, включая новые
                int a = (int) (Math.random() * chromosomes.length + i);
                int b = (int) (Math.random() * chromosomes.length + i);
                if (chromosomes.length + i >= 750) {
                    System.out.println("fdsfsdf");
                }
                Chromosome cross = multiplicationResult[a].cross(multiplicationResult[b]);
                
                multiplicationResult[chromosomes.length + i] = cross;

            }
        } catch (Exception ex) {
            System.out.println(""+chromosomes.length + num);
        }
        return multiplicationResult;
    }
}
